package com.example.httplibrary.https

import com.example.baselibrary.bases.Constants
import com.example.baselibrary.utlis.LogUtils
import com.example.baselibrary.utlis.Md5Util
import com.xuexiang.xui.BuildConfig
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.RequestBody
import okio.Buffer
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit
import retrofit2.Converter
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl

/**
 * @author 郑
 * @date 2025/8/4.
 * qq：331758871
 * phone：18979397268
 */
/**
 * Retrofit 客户端单例对象，用于管理网络请求的配置和 Retrofit 实例。
 * 支持动态设置 BaseUrl、Token 提供者、通用参数拦截器、日志拦截器等功能。
 */
object RetrofitClient {
    private const val DEFAULT_BASE_URL = "https://your-api-base-url.com/"
    private const val DEFAULT_TIMEOUT = 30L

    private val retrofitLock = Any()
    private val retrofitMap = ConcurrentHashMap<String, Retrofit>()
    private val retrofitWithoutParamsMap = ConcurrentHashMap<String, Retrofit>() // 用于存储不带通用参数的Retrofit实例

    // 单例 OkHttpClient 实例
    private val okHttpClient: OkHttpClient by lazy { createOkHttpClient() }

    @Volatile
    private var dynamicBaseUrl = DEFAULT_BASE_URL

    private var tokenProvider: (() -> String)? = null
    private var headersProvider: (() -> Map<String, String>)? = null

    /**
     * 设置动态 BaseUrl。
     *
     * @param newUrl 新的 BaseUrl 字符串。
     */
    fun setBaseUrl(newUrl: String) {
        // 确保 URL 格式正确，保留完整的路径
        val formattedUrl = formatBaseUrl(newUrl)
        if (dynamicBaseUrl != formattedUrl) {
            dynamicBaseUrl = formattedUrl
            // 清除所有缓存，确保使用最新的baseUrl
            clearAllRetrofitInstances()
        }
    }

    /**
     * 格式化 BaseUrl，确保路径正确保留
     *
     * @param url 原始 URL
     * @return 格式化后的 URL
     */
    private fun formatBaseUrl(url: String): String {
        return when {
            url.isEmpty() -> DEFAULT_BASE_URL
            !url.startsWith("http://") && !url.startsWith("https://") -> {
                // 如果没有协议，添加默认的 https
                "https://$url"
            }
            else -> url
        }
    }

    /**
     * 设置 Token 提供者函数。
     *
     * @param provider 返回 Token 字符串的无参函数。
     */
    fun setTokenProvider(provider: () -> String) {
        tokenProvider = provider
    }

    /**
     * 设置请求头提供者函数
     *
     * @param provider 返回请求头键值对的函数
     */
    fun setHeadersProvider(provider: () -> Map<String, String>) {
        headersProvider = provider
    }

    /**
     * 日志拦截器，根据 Constants.DEBUG 控制日志输出级别。
     */
    private val loggingInterceptor = HttpLoggingInterceptor().apply {
        level = if (Constants.DEBUG) {
            HttpLoggingInterceptor.Level.BODY
        } else {
            HttpLoggingInterceptor.Level.NONE
        }
    }

    /**
     * Token 拦截器，在请求头中添加 Authorization、App-Version 和 Platform 信息。
     */
    private val tokenInterceptor = Interceptor { chain ->
        val original = chain.request()
        val token = getAuthToken()

        // 打印请求体信息（仅在调试模式下）
        if (Constants.DEBUG) {
            logRequestBody(original.body)
        }

        val requestBuilder = original.newBuilder()

        // 添加动态请求头
        headersProvider?.invoke()?.forEach { (key, value) ->
            requestBuilder.header(key, value)
        }

        // 添加认证头（如果存在token）
        if (token.isNotEmpty()) {
            requestBuilder.header("Authorization", "Bearer $token")
        }

        val request = requestBuilder
            .method(original.method, original.body)
            .build()

        return@Interceptor chain.proceed(request)
    }

    /**
     * 获取 Retrofit 实例，支持多 BaseUrl 缓存。
     *
     * @return 对应当前 BaseUrl 的 Retrofit 实例。
     */
    private fun getRetrofit(): Retrofit {
        return retrofitMap[dynamicBaseUrl] ?: synchronized(retrofitLock) {
            retrofitMap[dynamicBaseUrl] ?: buildRetrofit().also {
                retrofitMap[dynamicBaseUrl] = it
            }
        }
    }

    /**
     * 获取不带通用参数的 Retrofit 实例
     *
     * @return 对应当前 BaseUrl 的不带通用参数的 Retrofit 实例。
     */
    private fun getRetrofitWithoutCommonParams(): Retrofit {
        return retrofitWithoutParamsMap[dynamicBaseUrl] ?: synchronized(retrofitLock) {
            retrofitWithoutParamsMap[dynamicBaseUrl] ?: buildRetrofitWithoutCommonParams().also {
                retrofitWithoutParamsMap[dynamicBaseUrl] = it
            }
        }
    }

    /**
     * 构建一个新的 Retrofit 实例。
     *
     * @return 新构建的 Retrofit 实例。
     */
    private fun buildRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(parseBaseUrl(dynamicBaseUrl))
            .client(okHttpClient) // 复用单例 OkHttpClient
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    /**
     * 构建一个不带通用参数拦截器的 Retrofit 实例。
     *
     * @return 新构建的不带通用参数拦截器的 Retrofit 实例。
     */
    private fun buildRetrofitWithoutCommonParams(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(parseBaseUrl(dynamicBaseUrl))
            .client(createOkHttpClientWithoutCommonParams()) // 使用不带通用参数的 OkHttpClient
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    /**
     * 解析并构建正确的 Base URL
     *
     * @param urlString 原始 URL 字符串
     * @return 正确解析的 HttpUrl 对象
     */
    private fun parseBaseUrl(urlString: String): HttpUrl {
        return urlString.toHttpUrl()
    }

    /**
     * 创建并配置 OkHttpClient 实例。
     *
     * @return 配置完成的 OkHttpClient 实例。
     */
    private fun createOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder().apply {
            connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)

            // 添加拦截器
            addInterceptor(tokenInterceptor)
            addInterceptor(loggingInterceptor)
            addInterceptor(createCommonParamsInterceptor())

            if (BuildConfig.DEBUG) {
                // 调试模式额外配置
            }
        }.build()
    }

    /**
     * 创建不带通用参数拦截器的 OkHttpClient 实例。
     *
     * @return 配置完成的不带通用参数拦截器的 OkHttpClient 实例。
     */
    private fun createOkHttpClientWithoutCommonParams(): OkHttpClient {
        return OkHttpClient.Builder().apply {
            connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
            writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)

            // 只添加必要的拦截器，不添加通用参数拦截器
            addInterceptor(tokenInterceptor)
            addInterceptor(loggingInterceptor)

            if (BuildConfig.DEBUG) {
                // 调试模式额外配置
            }
        }.build()
    }

    /**
     * 创建通用参数拦截器，为所有请求添加 platform 和 version 查询参数。
     *
     * @return 通用参数拦截器。
     */
    private fun createCommonParamsInterceptor(): Interceptor {
        return Interceptor { chain ->
            val original = chain.request()
            val originalUrl = original.url
            val newUrl = originalUrl.newBuilder()
                .build()
            chain.proceed(original.newBuilder().url(newUrl).build())
        }
    }

    /**
     * 创建指定接口的 Retrofit 服务实例。
     *
     * @param service 接口类的 Class 对象。
     * @return Retrofit 生成的服务实例。
     */
    fun <T> createService(service: Class<T>): T {
        return getRetrofit().create(service)
    }

    /**
     * 创建指定接口的 Retrofit 服务实例（不带通用参数）。
     *
     * @param service 接口类的 Class 对象。
     * @return Retrofit 生成的服务实例。
     */
    fun <T> createServiceWithoutCommonParams(service: Class<T>): T {
        return getRetrofitWithoutCommonParams().create(service)
    }

    /**
     * 创建指定接口的 Retrofit 服务实例，并可自定义 Converter.Factory。
     *
     * @param service 接口类的 Class 对象。
     * @param converterFactories 可变参数，传入自定义的 Converter.Factory。
     * @return Retrofit 生成的服务实例。
     */
    fun <T> createService(
        service: Class<T>,
        vararg converterFactories: Converter.Factory
    ): T {
        return getRetrofit().newBuilder()
            .apply {
                converterFactories.forEach { addConverterFactory(it) }
            }
            .build()
            .create(service)
    }

    /**
     * 获取当前的认证 Token。
     *
     * @return 当前 Token 字符串，若未设置则返回空字符串。
     */
    private fun getAuthToken(): String {
        return tokenProvider?.invoke() ?: ""
    }

    /**
     * 清理指定 BaseUrl 的 Retrofit 实例
     *
     * @param baseUrl 需要清理的 BaseUrl
     */
    fun clearRetrofitInstance(baseUrl: String) {
        synchronized(retrofitLock) {
            retrofitMap.remove(baseUrl)
            retrofitWithoutParamsMap.remove(baseUrl)
        }
    }

    /**
     * 清理所有缓存的 Retrofit 实例
     */
    fun clearAllRetrofitInstances() {
        synchronized(retrofitLock) {
            retrofitMap.clear()
            retrofitWithoutParamsMap.clear()
        }
    }

    /**
     * 移除 TokenProvider 引用，避免内存泄漏
     */
    fun clearTokenProvider() {
        tokenProvider = null
    }

    /**
     * 移除 HeadersProvider 引用，避免内存泄漏
     */
    fun clearHeadersProvider() {
        headersProvider = null
    }

    /**
     * 打印请求体内容
     *
     * @param requestBody 请求体对象
     */
    private fun logRequestBody(requestBody: RequestBody?) {
        if (!Constants.DEBUG) return

        try {
            if (requestBody != null) {
                val buffer = Buffer()
                requestBody.writeTo(buffer)

                // 尝试读取UTF-8格式的内容
                val bodyString = buffer.readUtf8()
                println("=== Request Body Start ===")
                println(bodyString)
                println("=== Request Body End ===")
            } else {
                println("Request Body: (empty)")
            }
        } catch (e: Exception) {
            println("Failed to log request body: ${e.message}")
        }
    }
}
